﻿using Api.Common;
using Api.IRepository;
using Api.IServices;
using Api.Model.Dto.ArticleDto;
using Api.Model.Model;
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Api.Services
{
    public class ArticleServices :BaseServices<Article, int>,IArticleServices
    {
        private readonly IArticleRepository _articleRepository;
        private readonly IArticleTypeRepository _articleTypeRepository;
        private readonly ITagRepository _tagRepository;
        private readonly IMapper _mapper;
        private readonly ITagArticleRepository _tagArticleRepository;

        public ArticleServices(IArticleRepository articleRepository,IArticleTypeRepository articleTypeRepository,ITagRepository tagRepository,IMapper mapper,ITagArticleRepository tagArticleRepository)
            :base(articleRepository)
        {
            _articleRepository = articleRepository;
            _articleTypeRepository = articleTypeRepository;
            _tagRepository = tagRepository;
            _mapper = mapper;
            _tagArticleRepository = tagArticleRepository;
        }

        public async Task CreateArticleAsync(CreateArticleInput input)
        {
            
            if (input.TagIds.Count.Equals(0))
            {
                throw new UIException("标签不能为空！");
            }
            var a = _mapper.Map<Article>(input);
            await ValidateArticleTitle(a);
            await _articleRepository.AddAsync(a);
        }

        public async Task DeleteArticle(int id)
        {
            if (await GetByIdIncludeNavAsync(id) is Article article)
            {
                File.Delete(StaticInfo.WebRootPath + article.Url);
                _tagArticleRepository.DeleteRange(article.TagArticles);
                await _articleRepository.DeleteAsync(article);
            }
        }

        public async Task<GetArticleOutput> GetArticleAsync(int? id)
        {
            var res = await GetALL().Include(x=>x.TagArticles).ThenInclude(x=>x.Tag).SingleOrDefaultAsync(x=>x.Id.Equals(id.GetValueOrDefault()));
            if (res == null)
            {
                throw new UIException("文章不存在!");
            }
            return _mapper.Map<GetArticleOutput>(res); 
        }

        public async Task<List<GetArticleListOutput>> GetArticlePageListAsync(GetArticleInput input)
        {
            List<Article> res = null; 
            if (input.TagId.HasValue)
            {
                res = (await _tagArticleRepository.GetALL().Include(x=>x.Article).Include(x => x.Tag).Where(x=>x.TagId.Equals(input.TagId)).AsNoTracking().Skip(input.PageModel.PageIndex* input.PageModel.PageSize).Take(input.PageModel.PageSize).ToListAsync()).Select(x => x.Article).ToList();
                
            }
            if (input.ArticleTypeId.HasValue)
            {
                res= (await _articleTypeRepository.GetByIdIncludeNavAsync(input.ArticleTypeId.Value)).Articles;
            }
            else
            {
                res = await _articleRepository.GetALL().Include(x=>x.TagArticles).ThenInclude(x=>x.Tag).AsNoTracking().Skip(input.PageModel.PageIndex * input.PageModel.PageSize).Take(input.PageModel.PageSize).ToListAsync();
            }
            return _mapper.Map<List<GetArticleListOutput>>(res);
        }

        public async Task UpdateArticle(UpdateArticleInput input)
        {
            
            if (!(await GetByIdIncludeNavAsync(input.Id.Value) is Article article))
            {
                throw new UIException("文章不存在！");
            }
            if (input.TagIds.Count.Equals(0))
            {
                throw new UIException("标签不能为空！");
            }
            _mapper.Map(input, article);
            await ValidateArticleTitle(article);
            File.WriteAllText(StaticInfo.WebRootPath + article.Url, input.Body);
        }

        private async Task ValidateArticleTitle(Article article)
        {
            if (await _articleRepository.AnyAsync(x=>x.Title.Equals(article.Title)&&!x.Id.Equals(article.Id)))
            {
                throw new UIException("文章标题重复");
            }
        }

    }
}
